"""
量能可靠性验证器
解决开盘量比失真的核心逻辑
"""
import logging
import numpy as np
from ..base import SignalValidator, ValidationContext, ValidationResult

logger = logging.getLogger('VolumeReliabilityValidator')


class VolumeReliabilityValidator(SignalValidator):
    """
    量能可靠性验证器
    检查：
    1. 绝对成交量是否达到最小阈值
    2. 量比是否稳定（不是瞬时波动）
    3. 成交量趋势是否正常
    """
    
    def __init__(self, min_volume_ratio: float = 0.2, volatility_threshold: float = 0.4):
        """
        Args:
            min_volume_ratio: 最小成交量相对历史平均的比例
            volatility_threshold: 量比波动率阈值
        """
        self.min_volume_ratio = min_volume_ratio
        self.volatility_threshold = volatility_threshold
    
    def validate(self, context: ValidationContext) -> ValidationResult:
        """验证量能可靠性"""
        current_data = context.stock_data.iloc[context.current_index]
        
        # 检查1: 绝对成交量
        min_threshold = self._get_min_volume_threshold(context)
        volume_check = current_data['volume'] >= min_threshold
        
        # 检查2: 量比稳定性
        stability_check = self._check_volume_stability(context)
        
        # 检查3: 成交量趋势
        trend_check = self._check_volume_trend(context)
        
        # 所有检查都要通过
        passed = volume_check and stability_check and trend_check
        
        # 计算置信度（通过的检查数量 / 总检查数量）
        confidence = sum([volume_check, stability_check, trend_check]) / 3
        
        details_parts = []
        details_parts.append(f"成交量:{'🟢' if volume_check else '🔴'}")
        details_parts.append(f"稳定性:{'🟢' if stability_check else '🔴'}")
        details_parts.append(f"趋势:{'🟢' if trend_check else '🔴'}")
        
        return ValidationResult(
            passed=passed,
            validator_name=self.get_name(),
            details="，".join(details_parts),  # ⭐ 改用中文逗号，避免与外层" | "分隔符冲突
            confidence=confidence
        )
    
    def _get_min_volume_threshold(self, context: ValidationContext) -> float:
        """
        计算最小成交量阈值
        基于历史成交量动态计算
        """
        if context.current_index < 10:
            return 100000  # 默认10万股
        
        # 基于历史成交量动态计算阈值
        recent_volumes = context.stock_data.iloc[
            max(0, context.current_index-10):context.current_index
        ]['volume']
        avg_volume = recent_volumes.mean()
        
        # 阈值为近期平均成交量的20%
        return avg_volume * self.min_volume_ratio
    
    def _check_volume_stability(self, context: ValidationContext, window: int = 5) -> bool:
        """
        检查量比稳定性
        波动率小于阈值才认为稳定
        """
        if context.current_index < window:
            return True  # 数据不足时放宽要求
        
        try:
            volume_ratios = []
            for i in range(max(0, context.current_index-window+1), context.current_index+1):
                data = context.stock_data.iloc[i]
                if 'volume_ratio' in data:
                    volume_ratios.append(data['volume_ratio'])
            
            if len(volume_ratios) < 2:
                return True
            
            # 计算量比波动率（变异系数 CV = std/mean）
            mean_ratio = np.mean(volume_ratios)
            if mean_ratio == 0:
                return False
            
            volatility = np.std(volume_ratios) / mean_ratio
            
            # 波动率小于阈值视为稳定
            return volatility < self.volatility_threshold
            
        except Exception as e:
            logger.warning(f"量比稳定性检查异常: {e}")
            return True  # 异常时放宽要求
    
    def _check_volume_trend(self, context: ValidationContext) -> bool:
        """
        检查成交量趋势
        避免成交量急剧萎缩导致的误判
        """
        if context.current_index < 1:
            return True
        
        try:
            current_volume = context.stock_data.iloc[context.current_index]['volume']
            prev_volume = context.stock_data.iloc[context.current_index-1]['volume']
            
            # 允许成交量正常波动，但不能急剧萎缩
            # 不低于前期的30%
            return current_volume >= prev_volume * 0.3
            
        except Exception as e:
            logger.warning(f"成交量趋势检查异常: {e}")
            return True
    
    def get_name(self) -> str:
        return "量能可靠性确认"

